from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.
from rest_framework.response import Response

from goods.models import SKU
from users.models import User
from users.utils import check_active_token

"""

一  确定需求
二 把需求拆分成我们的步骤
三 确定请求方式和 url
四 确定视图,实现代码

前端当光标移开的时候,发送一个 ajax请求, 这个请求需要携带 用户注册的用户名

#
# 1.接收参数
# 2.判断用户名是否注册(存在)
# 3.返回响应

GET         /users/usernames/(?P<username>\w{5,20})/
"""
# APIView
#GenericAPIView                     列表,视图做了通用支持,一般和mixin配置使用
#ListAPIView,RetrieveAPIView
from rest_framework.views import APIView

class RegisterUsernameView(APIView):
    def get(self,request,username):
        count = User.objects.filter(username=username).count()
        return Response({'count':count,'username':username})

"""
用户点击注册按钮的时候,前端需要将 6个参数(mobile,password,password2,username,sms_code,allow)
传递给后端

#
# 1.接收参数
# 2.校验参数
# 3.数据入库
# 4.返回响应

POST        /users/


"""
# APIView
#GenericAPIView                     列表,视图做了通用支持,一般和mixin配置使用
#CreateAPIView
from rest_framework.mixins import CreateModelMixin
from .serializers import RegisterCreateUserSerializer


class RegisterCreateUserView(APIView):

    def post(self,request):
        # 1.接收参数
        data = request.data
        # 2.校验参数 -->序列化器中
        serializer = RegisterCreateUserSerializer(data=data)
        serializer.is_valid(raise_exception=True)
        # 3.数据入库
        serializer.save()
        # 4.返回响应
        # serializer.data
        # 序列化操作(将对象转换为字典)
        # 序列化的操作 是根据 序列化器的字段 去获取模型中的数据,来转换为字典的

        # serializer.data 在 序列化操作(将对象转换为字典)
        # serializer.data 中没有token

        # 序列化的操作 是根据 序列化器的字段 去获取模型中的数据,来转换为字典的
        return Response(serializer.data)

"""
当用户注册完成之后, 让用户自动登录,


 当用户注册完成之后 返回一个 token

 1.在注册成功之后,返回token
 2.token没有,不知道怎么生成


"""
# APIView
#GenericAPIView                     列表,视图做了通用支持,一般和mixin配置使用
#ListAPIView,RetrieveAPIView
from rest_framework.generics import RetrieveAPIView
from rest_framework.permissions import IsAuthenticated
from .serializers import UserCenterInfoSerializer
# class UserCenterInfoView(APIView):
#
#     """
#     个人中心界面只能是 登录用户访问, 前端 通过在header中 添加token
#
#     # 1. 这个接口只能用登录用户访问
#     # 2. 获取登录用户的信息 user
#     # 3. 创建序列化器
#     # 4. 返回数据
#
#     GET     users/infos/
#
#     """
#
#     # 1. 这个接口只能用登录用户访问
#     permission_classes = [IsAuthenticated]
#
#     def get(self,request):
#
#         # 2. 获取登录用户的信息 user
#         # user = User.objects.get(id=id)
#         user = request.user
#         #3. 创建序列化器
#         serializer = UserCenterInfoSerializer(user)
#         # 4. 返回数据
#         return Response(serializer.data)

class UserCenterInfoView(RetrieveAPIView):
    serializer_class = UserCenterInfoSerializer

    # queryset = User.objects.all()

    # 权限
    permission_classes = [IsAuthenticated]

    # 重写 get_object()
    def get_object(self):
        return self.request.user

from rest_framework.generics import UpdateAPIView
from .serializers import UserUpdateEmailSerializer

#
#     """
#
#     用户填写完邮箱之后,点击保存,前端应该将  email 和 token信息发送给后端
#
#     1.接收数据
#     2.对数据进行校验
#     3.更新数据
#     4.发送激活邮件
#     5.返回响应
#
#     PUT     /users/emails/
#
#     """
# class UserUpdateEmailView(UpdateAPIView):

    # def put(self,request):
    #     # 1.接收数据
    #     data = request.data
    #     user = request.user
    #     # 2.对数据进行校验
    #     serializer = UserUpdateEmailSerializer(instance=user,data=data)
    #     serializer.is_valid(raise_exception=True)
    #     # 3.更新数据
    #     serializer.save()
    #     # 4.发送激活邮件
    #
    #     # 5.返回响应
    #     return Response(serializer.data)

class UserUpdateEmailView(UpdateAPIView):

    serializer_class = UserUpdateEmailSerializer

    # queryset = User.objects.all()

    def get_object(self):

        return self.request.user

from rest_framework import status
class UserEmailActiveView(APIView):


    """
        用户点击激活按钮, 跳转到前端页面,前段页面可以 获取到token
        前端获取到token之后,需要将 token发送给后端


        1.接收token
        2.对token进行解密,解码获取id
        3.根据id获取user信息
        4.修改user的激活状态
        5.返回响应

        GET     /users/emails/verification/?token=xxx

        """
    def get(self,request):
        #
        # 1.接收token
        token = request.query_params.get('token')
        if token is None:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        # 2.对token进行解密,解码获取id
        user_id = check_active_token(token)
        if user_id is None:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        # 3.根据id获取user信息
        try:
            user = User.objects.get(id=user_id)
        except User.DoesNotExist:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        # 4.修改user的激活状态
        user.email_active=True
        user.save()
        # 5.返回响应
        return Response({'msg':'ok'})


"""

当用户填写完信息之后, 点击保存,前端发送一个ajax请求,将参数传递过来, 这个时候 user信息 以jwt的方式
传递过来

1.接收数据
2.对数据进行校验
3.数据保存
4.返回响应

POST        /users/addresses/

"""
from rest_framework.generics import CreateAPIView
from .serializers import AddressSerializer
class AddressView(CreateAPIView):
    serializer_class = AddressSerializer

    # query_set 在 CreateAPIView 是使用不到 查询结果集的

"""

string:     key:value
hash        hash_key:  key:value
list        list_key: value2,value5,value2,...
set         set_key: value2,value5,value1,...
zset        zset_key: value1,value2,value5,....


1. 登录用户才可以访问 用户浏览记录接口
2. 我们只记录登录用户的浏览记录
3. 我们用redids来保存浏览历史记录 , 列表
4. 应该是在用户访问 商品详情的时候 去记录浏览记录



添加浏览记录 POST     users/browerhistories/

    当用户访问商品详情的时候,前端应该发送一个ajax请求,这个请求应该包含 商品id,和用户信息(JWT)

    1.接收数据,校验数据
    2.保存数据
    3.返回响应


获取浏览记录 GET

    1.登录用户访问
    2.我们就从redis中获取数据 [16,1,2]
    3.根据id查询商品的详细信息 [SKU,SKU,SKU]
    4.返回响应


"""

#APIView
#GenericAPIView
#CreateAPIView
from .serializers import UserHistorySerializer,SKUSerializer
from django_redis import get_redis_connection
class UserHistoryView(APIView):


    permission_classes = [IsAuthenticated]

    def post(self,request):

        user = request.user

        # 1.接收数据,校验数据
        serializer = UserHistorySerializer(data=request.data)

        serializer.is_valid(raise_exception=True)
        # 2.保存数据 -- redis
        # serializer.save()

        sku_id = serializer.validated_data.get('sku_id')
        #2.1 连接redis
        redis_conn = get_redis_connection('history')

        #2.2 先把 sku_id 可能在列中的数据 删除
        redis_conn.lrem('history_%s'%user.id,0,sku_id)

        #2.3 写入redis的列表中
        # history_user_id: [1,2,3]
        redis_conn.lpush('history_%s'%user.id,sku_id)

        #2.4 通过ltrim 对列表进行修剪
        redis_conn.ltrim('history_%s'%user.id,0,4)

        # 3.返回响应
        return Response(serializer.data)


    def get(self,request):
        # 1.登录用户访问
        user = request.user
        # 2.我们就从redis中获取数据 [16,1,2]
        redis_conn = get_redis_connection('history')

        sku_ids = redis_conn.lrange('history_%s'%user.id,0,5)
        #[1,2,3]

        # 3.根据id查询商品的详细信息 [SKU,SKU,SKU]
        # 通过in 去取数据的时候 顺序会错乱
        # 所以我们不能采用 in来取数据
        # skus = SKU.objects.filter(id__in=sku_ids)
        #  [SKU,SKU,SKU]
        skus = []

        for sku_id in sku_ids:
            sku = SKU.objects.get(pk=sku_id)
            skus.append(sku)

        serializer = SKUSerializer(skus,many=True)
        # 4.返回响应
        return Response(serializer.data)


































































